/**
 * License would add here
 */

#ifndef UTILS_JS_DATE_H
#define UTILS_JS_DATE_H

#include <node_api.h>

#include <csignal>
#include <cstring>

#include "js_native_api.h"
#include "js_native_api_types.h"
#include "js_number.h"
#include "js_object.h"
#include "js_value_base.h"
#include "macros.h"

#define IS_DDATE(type) VALUE_TYPE_CHECK((IsObject() && IsDate()), "date", (type))
#define IS_DDATE_OR_NUMBER(type) VALUE_TYPE_CHECK(((IsObject() && IsDate()) || IsNumber()), "date or number", (type))

class JSDate : public JSObject {
public:
    JSDate(const JSNumber& value)
        : JSObject(GetEnv(value), true)
    {
        NAPI_STATUS_CALL(env_, napi_create_date(env_, value, &value_));
        UpdateType();
    }
    JSDate(const napi_env& env, double value)
        : JSObject(env, true)
    {
        NAPI_STATUS_CALL(env_, napi_create_date(env, value, &value_));
        UpdateType();
    }
    JSDate(const JSValue& value)
        : JSObject(value)
    {
        IS_DDATE_OR_NUMBER(type_);
        if (IsNumber()) {
            NAPI_STATUS_CALL(env_, napi_create_date(env_, JSNumber(value), &value_));
        } else if (IsObject() && IsDate()) {
            value_ = value;
        }
        UpdateType();
    };
    JSDate(const JSDate& value)
        : JSObject(value) {};

    inline double GetValue() const
    {
        double result;
        NAPI_STATUS_CALL(env_, napi_get_date_value(env_, value_, &result));
        return result;
    }

    inline operator double() const { return GetValue(); }

private:
};

#undef IS_DDATE
#undef IS_DDATE_OR_NUMBER
#endif /* UTILS_JS_DATE_H */
